package org.sipsl.gisystems.gentest.rte.util.license;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.security.PublicKey;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.Cipher;

import org.sipsl.gisystems.gentest.rte.util.GenericUtil;

public class GetLicense {
	
	
	/**
	 * String to hold name of the encryption algorithm.
	 */
	private static final String ALGORITHM = "RSA";

	/**
	 * String to hold name of the public key file.
	 */
	private static String PUBLIC_KEY_FILE = "public.key";


	

	public static void isValid(String license, String publicKeyFile){
		
		if (publicKeyFile != null){
			PUBLIC_KEY_FILE = publicKeyFile;
		}
		
		DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
		Date date = new Date();

		String myDate = dateFormat.format(date);
		String macAddress = getMacAddress();

		String[] readedFromFile = license.split(":");
		byte[] readedFromFileByte = new byte[readedFromFile.length];
		for (int i = 0; i < readedFromFile.length; i++) {
			Byte x = Byte.valueOf(readedFromFile[i]);
			readedFromFileByte[i] = x;
		}

		byte[] cipherText = readedFromFileByte;

		ObjectInputStream inputStream = null;

		try {
			inputStream = new ObjectInputStream(new FileInputStream(
					PUBLIC_KEY_FILE));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		PublicKey publicKey = null;
		try {
			publicKey = (PublicKey) inputStream
					.readObject();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		final String plainText = decrypt(cipherText, publicKey);

		String[] parts = plainText.split("#");
		System.out.println(parts[0] + " " + parts[1]);
		Date licenseEnd = null;
		try {
			licenseEnd = dateFormat.parse(parts[0]);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (parts[1].compareTo(macAddress) != 0){
			System.out.println("Wrong machine");
			System.exit(0);
		}
		else if (licenseEnd.compareTo(date) < 0)  {
			System.out.println("expired");
			System.exit(0);
		}
	}
	
	private static String getMacAddress() {

		String command = "/sbin/ifconfig";
		String args[] = new String[2];

		String line = "";

		String sOsName = System.getProperty("os.name");
		if (sOsName.startsWith("Windows")) {
			command = "ipconfig";
		} else {

			if ((sOsName.startsWith("Linux")) || (sOsName.startsWith("Mac"))
					|| (sOsName.startsWith("HP-UX"))) {
				command = "/sbin/ifconfig";
			} else if ( sOsName.startsWith("SunOS") ){
				args[0] = "/bin/netstat";
				args[1] = "-pn";
			}else{
				System.out.println("The current operating system '" + sOsName
						+ "' is not supported.");
			}
		}

		Pattern p = Pattern
				.compile("([a-fA-F0-9]{1,2}(-|:)){5}[a-fA-F0-9]{1,2}");
		try {
			Process pa;
			if (sOsName.startsWith("SunOS") ){
				pa = Runtime.getRuntime().exec(args);
			}else {
				pa = Runtime.getRuntime().exec(command);
			}
			pa.waitFor();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					pa.getInputStream()));

			Matcher m;

			while ((line = reader.readLine()) != null) {
				//System.out.println("line " + line);
				if (!sOsName.startsWith("SunOS") || line.contains("SP")){

					m = p.matcher(line);
	
					
					if (!m.find())
						continue;
					line = m.group();
//					System.out.println("line is " + line);
					break;
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return line;

	}

	private static String decrypt(byte[] text, PublicKey key) {
		byte[] dectyptedText = null;
		try {
			// get an RSA cipher object and print the provider
			final Cipher cipher = Cipher.getInstance(ALGORITHM);

			// decrypt the text using the private key
			cipher.init(Cipher.DECRYPT_MODE, key);
			dectyptedText = cipher.doFinal(text);

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return new String(dectyptedText);
	}

}
